
// Copyright (c) WanSheng Intelligent Corp. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#ifndef __WA_COAP_SDK__H_
#define __WA_COAP_SDK__H_

#include "plugin_constants.h"
#include "plugin_dlist.h"
#include "wa_sdk.h"
#include "er-coap.h"

#ifdef __cplusplus
extern "C" {
#endif

#define PORT_UNDEFINED -1


typedef struct net_addr * WA_NET_ADDR;
typedef int (*WA_Tx_Data) (void * coap_ctx, const WA_NET_ADDR dst_addr, void *buf, int len);
typedef int (*WA_Rx_Data) (void * coap_ctx, void *buf, int len, int timeout);

WA_Tx_Data wa_coap_get_default_TX();

WA_Rx_Data wa_coap_get_default_RX();

coap_context_t * wa_coap_get_context(RESTFUL_CONTEXT );

WA_NET_ADDR wa_addr_set_IP(net_addr_t * addr, const char * IP, int port);

/*
    @param port:        port used for sending and recieving UDP packet
                        PORT_UNDEFINED(-1) - means a random port will be used.
    @param timeout_ms:  milliseconds for timeout if no reponse recieved
    @param retras:      max retransmissions before failing the request sending.
                        0 - means only send once in total
*/
RESTFUL_CONTEXT wa_coap_init_context(int port, int timeout_ms, int retrans);

int wa_coap_get_socket(RESTFUL_CONTEXT);

void wa_set_response_coap(REQ_ENV_HANDLE env, coap_packet_t * coap_message);

/*
    @brief: send a request and the response or timeout will be tigger the response_handler.
    @param  request:    the parameter request should carry the target addr,
                        like: coap//192.168.1.11:5683/abc/efg
*/
bool wa_coap_request(RESTFUL_CONTEXT restful_context, 
    restful_request_t * request, 
    WA_Result_Handler response_handler, void * user_data);

bool wa_coap_request_to_addr(RESTFUL_CONTEXT restful_context, 
    restful_request_t * request, 
    WA_Result_Handler response_handler, void * user_data, WA_NET_ADDR dest);

bool wa_coap_request_to_IP(RESTFUL_CONTEXT restful_context, 
    restful_request_t * request, 
    WA_Result_Handler response_handler, void * user_data, const char* IP, int port);

restful_response_t * wa_coap_request_wait_IP(RESTFUL_CONTEXT restful_context, 
    restful_request_t * request, const char * IP, int port);

restful_response_t * wa_coap_request_wait(RESTFUL_CONTEXT restful_context, 
    restful_request_t * request, WA_NET_ADDR dest);

// register the url that this plugin will serve and handling function
//* url match patterns:
// * sample 1: /abcd, match "/abcd" only
// * sample 2: /abcd/ match match "/abcd" and "/abcd/*"
// * sample 3: /abcd*, match any url started with "/abcd"
// * sample 4: /abcd/*, exclude "/abcd"
void wa_coap_register_resource(RESTFUL_CONTEXT context, const char * url, WA_Resource_Handler handler, rest_action_t action);



void wa_coap_set_poster(RESTFUL_CONTEXT restful_context, RestfulRemoteHandler poster, void * arg);

// return the milliseconds to the nearest expiry time
uint32_t wa_coap_check_expiry(RESTFUL_CONTEXT context);

/*
    @param  timeout_ms: the max milliseconds for waiting.
                        0 - nonblocking recieve.
*/
void wa_coap_recieve_process(RESTFUL_CONTEXT context, int timeout_ms);

/*
    @brief  wakeup the thread who is under calling wa_coap_recieve_process()
*/
void wa_coap_wakeup_recieving_thread(RESTFUL_CONTEXT context);


/**********************************************************************
**
**                  Send simple packet
**
************************************************************************/


void wa_coap_send_request(restful_request_t * request, const char * IP, int port);

#ifdef __cplusplus
}
#endif


#endif /* __WA_PLUGIN_SDK__H_ */
